/*
 * #%L
 * java model
 * %%
 * Copyright (C) 2009 - 2011 prefabware.com Stefan Isele
 * %%
 * All Rights Reserved.
 * This program is dual-licensed under the GNU General Public license
 * or a commercial license.
 * You may select to use one or the other of these licenses.
 * To obtain a commercial license please contact Stefan Isele at www.stefan-isele.de
 * Any modifications to this file must keep this entire header intact.
 * Redistribution, except as permitted by the selected license, is prohibited.
 * #L%
 */
package com.prefabware.jmodel;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.prefabware.commons.CollectionUtil;
import com.prefabware.commons.collection.Gettable;
import com.prefabware.jmodel.code.JCodable;
import com.prefabware.jmodel.code.JCodeOptions;

public class JModifiers implements JCodable{

	/**
	 * theses constants allow to create a JModifiers with single modifier in a convinient way 
	 */
	public static final JModifiers ABSTRACT = new JModifiers(JModifier.ABSTRACT);
	public static final JModifiers FINAL = new JModifiers().add(JModifier.FINAL);
	public static final JModifiers NATIVE = new JModifiers().add(JModifier.NATIVE);
	public static final JModifiers STATIC = new JModifiers().add(JModifier.STATIC);
	public static final JModifiers SYNCHRONIZED = new JModifiers().add(JModifier.SYNCHRONIZED);
	public static final JModifiers TRANSIENT = new JModifiers().add(JModifier.TRANSIENT);
	public static final JModifiers VOLATILE = new JModifiers().add(JModifier.VOLATILE);
	public static final JModifiers NONE = new JModifiers();
	public static final JModifiers FINAL_STATIC = new JModifiers().add(JModifier.FINAL).add(JModifier.STATIC);
	private List<JModifier> modifiers;

	public boolean contains(JModifier modifier) {
		return modifiers.contains(modifier);
	}

	public JModifiers() {
		super();
		this.modifiers = new ArrayList<JModifier>();
	}

	public JModifiers(JModifier... modifier) {
		this();
		this.modifiers.addAll(Arrays.asList(modifier));
	}

	public JModifiers add(JModifier modfier) {
		modifiers.add(modfier);
		return this;
	}

	public List<JModifier> getModifiers() {
		return modifiers;
	}

	public String asCode(JCodeOptions options) {
		Gettable<String, JModifier> gettable = new Gettable<String, JModifier>() {

			@Override
			public String get(JModifier from) {
				return from.toString();
			}
		};
		List<String> list = CollectionUtil.getList(gettable, this.modifiers);
		return CollectionUtil.seperatedBy(list, " ");
	}

	@Override
	public String toString() {
		return "JModifiers [modifiers=" + modifiers + "]";
	}

	public static JModifiers getModifier(int mod) {
		JModifiers modifiers = new JModifiers();
		if (Modifier.isAbstract(mod)) {
			modifiers.add(JModifier.ABSTRACT);
		}
		if (Modifier.isFinal(mod)) {
			modifiers.add(JModifier.FINAL);
		}
		if (Modifier.isNative(mod)) {
			modifiers.add(JModifier.NATIVE);
		}
		if (Modifier.isStatic(mod)) {
			modifiers.add(JModifier.STATIC);
		}
		if (Modifier.isSynchronized(mod)) {
			modifiers.add(JModifier.SYNCHRONIZED);
		}
		if (Modifier.isTransient(mod)) {
			modifiers.add(JModifier.TRANSIENT);
		}
		if (Modifier.isVolatile(mod)) {
			modifiers.add(JModifier.VOLATILE);
		}
		return modifiers;
	}
}
